package com.xuecheng.learning.service.impl;

import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.dto.LearningProgressDto;
import com.xuecheng.commons.model.dto.RecordDto;
import com.xuecheng.commons.model.vo.*;
import com.xuecheng.commons.utils.AuthInfoHolder;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.api.ContentClient;
import com.xuecheng.learning.domain.CourseRecord;
import com.xuecheng.learning.mapper.CourseRecordMapper;
import com.xuecheng.learning.service.CourseRecordService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.media.api.MediaClient;
import com.xuecheng.search.api.SearchClient;
import com.xuecheng.web.exception.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * <p>
 * 选课记录 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-12-12
 */
@Service
public class CourseRecordServiceImpl extends ServiceImpl<CourseRecordMapper, CourseRecord> implements CourseRecordService {

    // 用户登录以后，查询选课记录
    @Override
    public ResponseResult<CourseRecordVo> myCourseRec(Long coursePubId) {
        // 1.通过TL获取用户id
        Long userId = AuthInfoHolder.getUserId();
        // 2.构建条件查询
        CourseRecord record = this.lambdaQuery()
                .eq(CourseRecord::getCoursePubId, coursePubId)
                .eq(CourseRecord::getUserId, userId).one();
        // 3.判断
        if (record != null) {
            // 转vo并返回
            CourseRecordVo vo = BeanHelper.copyProperties(record, CourseRecordVo.class);
            return ResponseResult.okResult(vo);
        } else {
            // 直接返回ok
            return ResponseResult.okResult();
        }
    }

    @Autowired
    private SearchClient searchClient;

    // 支付成功，保存或更新选课记录
    @Override
    public ResponseResult saveRecord(RecordDto dto) {
        // 1.查询选课记录
        CourseRecord courseRecord = this.lambdaQuery().eq(CourseRecord::getUserId, dto.getUserId())
                .eq(CourseRecord::getCoursePubId, dto.getCoursePubId())
                .one();
        if (courseRecord != null) {// 2.查到了，修改paid=1
            courseRecord.setPaid(1);
            this.updateById(courseRecord);
        } else {//3.没查到，封装选课记录
            courseRecord = new CourseRecord();
            //3-1查询课程详情
            ResponseResult<CoursePubIndexVo> responseResult = searchClient.findById(dto.getCoursePubId().toString());
            if (responseResult.getCode() != 0) {
                throw new BusinessException(ErrorCode.NOTTOKEN);
            }
            CoursePubIndexVo vo = responseResult.getData();
            // 3-2 封装选课记录
            courseRecord.setUserId(dto.getUserId()); // 购买人id
            courseRecord.setCompanyId(vo.getCompanyId()); // 课程机构id
            courseRecord.setCourseId(vo.getCourseId()); // 课程id
            courseRecord.setCoursePubId(vo.getCourseId());// 课程发布id
            courseRecord.setCoursePubName(vo.getName()); // 课程名
            courseRecord.setTeachmode(vo.getTeachmode()); // 教学模式
            courseRecord.setCreateDate(new Date()); // 创建时间
            courseRecord.setPaid(1); // 已支付

            // 3-3 保存数据库
            this.save(courseRecord);
        }
        return ResponseResult.okResult();
    }

    @Autowired
    private ContentClient contentClient;

    @Autowired
    private MediaClient mediaClient;

    @Override
    public ResponseResult<ResourceVo> resourceUrl(Long coursePubId, Long mediaId, Long teachplanId) {
        // 1.查询此课程是否收费
        ResponseResult<CoursePubVo> coursePubVoResponseResult = contentClient.findById(coursePubId);
        if (coursePubVoResponseResult.getCode() != 0) {
            throw new BusinessException(ErrorCode.NOTFOUND);
        }
        CoursePubVo coursePubVo = coursePubVoResponseResult.getData();
        // 2.如果收费
        if (coursePubVo.getCharge().equals(CourseConstants.CHARGE_YES)) {// "201000"; 免费  "201001";收费
            // 2-1 查询用户此课程是否已支付
            CourseRecord courseRecord = this.lambdaQuery().eq(CourseRecord::getUserId, AuthInfoHolder.getUserId())
                    .eq(CourseRecord::getCourseId, coursePubId)
                    .one();
            // 2-2 判断 是否已支付
            if (courseRecord == null || courseRecord.getPaid() != 1) {
                // 3.用户未付款，此课程计划是否支持试学
                ResponseResult<TeachplanVo> teachplanVoResponseResult = contentClient.findTechplanById(teachplanId);
                if (teachplanVoResponseResult.getCode() != 0) {
                    throw new BusinessException(ErrorCode.NOTFOUND);
                }
                TeachplanVo teachplanVo = teachplanVoResponseResult.getData();
                // 试学  0 不支持  1支持
                if (teachplanVo.getIsPreview().equals("0")) {
                    // 4. 不支持试学
                    throw new BusinessException(ErrorCode.NOTPLAY);
                }
            }
        }
        // 5.正常返回播放地址（免费、支持试看、已付款）
        return mediaClient.mediaUrl(mediaId);
    }

    // 记录学习进度
    @Override
    public ResponseResult progress(LearningProgressDto dto) {
        // 1.查询选课记录
        CourseRecord courseRecord = this.lambdaQuery()
                .eq(CourseRecord::getUserId, AuthInfoHolder.getUserId())
                .eq(CourseRecord::getCourseId, dto.getCoursePubId())
                .one();
        // 2.如果有
        if (courseRecord != null) {
            // 更新选课记录
            courseRecord.setTeachplanId(dto.getTeachPlanId());
            courseRecord.setCoursePubName(dto.getTeachPlanName());
            // 更新到数据库
            this.updateById(courseRecord);
        }else {//3.如果没有
            //新增一条选课记录
            courseRecord = new CourseRecord();
            // 3-1 查询课程详情
            ResponseResult<CoursePubIndexVo> responseResult = searchClient.findById(dto.getCoursePubId().toString());
            if (responseResult.getCode() != 0) {
                throw new BusinessException(ErrorCode.NOTFOUND);
            }
            CoursePubIndexVo vo = responseResult.getData();
            // 3-2 封装选课记录
            courseRecord.setUserId(AuthInfoHolder.getUserId()); // 购买人id
            courseRecord.setCompanyId(vo.getCompanyId()); // 课程机构id
            courseRecord.setCourseId(vo.getCourseId()); // 课程id
            courseRecord.setCoursePubId(vo.getCourseId());// 课程发布id
            courseRecord.setCoursePubName(vo.getName()); // 课程名
            courseRecord.setTeachmode(vo.getTeachmode()); // 教学模式
            courseRecord.setCreateDate(new Date()); // 创建时间
            courseRecord.setTeachplanId(dto.getTeachPlanId()); // 课程计划id
            courseRecord.setTeachplanName(dto.getTeachPlanName()); // 课程计划名称

            // 3-3 保存数据库
            this.save(courseRecord);
        }
        // 4.返回ok
        return ResponseResult.okResult();
    }
}